package com.sxj.corejava.code11_io.字节流;

import java.io.*;
import java.util.Arrays;

/**
 * @author 石小俊
 */
public class Test01_文件字节流 {

    public static void main(String[] args) {
        test03();
    }

    /**
     * 每次读取一个字节
     */
    public static void test01() {
        FileInputStream in = null;
        try {
            File file = new File("hello.txt");
            in = new FileInputStream(file);
//            FileInputStream in = new FileInputStream("hello.txt");

//            int data = in.read();
//            System.out.println(data);
            // 无限读取的时候,发现当读取不到数据时其值返回-1
//            System.out.println(in.read());
            // 如果想要读取所有数据,可以通过循环实现,只要返回值不是-1就可以一直读取
            int data = -1;
            while ((data = in.read()) != -1) {
                System.out.print((char) data);
            }
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            // 在进行IO操作时,所有开启的流最终都需要释放
            // 实际开发中,遵循谁开谁关的原则
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    /**
     * 一次读取多个字节
     */
    public static void test02() {
        // 从JDK7开始引入了一个新的语法try-with-resource
        // 用于自动关闭外部资源,不需要手动关闭
        // 每次资源使用完毕之后会自动帮我们关闭
        try (
                // 将所有需要释放的资源在此处进行开启
                // 此处只能创建实现了AutoCloseable接口的对象
//                FileInputStream in = new FileInputStream("hello.txt");
                // 支持通过类加载直接找src目录下的资源
                InputStream in = Test01_文件字节流.class.getClassLoader().getResourceAsStream("user.properties");
        ) {
//            byte[] b = new byte[100];
            byte[] b = new byte[1024];
//            int data = in.read(b);
            // data:表示的是总字节数量
//            System.out.println(data);
//            System.out.println(Arrays.toString(b));
            int data = -1;
            while ((data = in.read(b)) != -1) {
//                System.out.print((char)data);
                System.out.println(new String(b, 0, data));
            }
        } catch (FileNotFoundException e) {
            System.out.println();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 向文件中写入内容
     */
    public static void test03() {
        try (
                FileOutputStream out = new FileOutputStream("b.txt");
        ) {
            // 写入数据,需要将一个字节数组作为参数使用
            // 因此,对于写入的数据需要先转换成字节数组才能使用
            byte[] data = "Hello World".getBytes();
            // 在写入数据时,只是将数据写入到了内存的缓冲区中,并没有真正写入到文件中
            out.write(data);
            // 此时需要刷新输出流,才会将缓冲区的数据写入到文件中
            // 刷新输出流的操作在释放资源前会自动调用
            // 刷新操作理论上是可以省略的,但是在实际开发中不建议省略
            out.flush();
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}
